package cn.com.bluemoon.daps.standard.service;

import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.com.bluemoon.daps.common.mp.IBmService;
import cn.com.bluemoon.daps.standard.common.CheckType;
import cn.com.bluemoon.daps.standard.vo.BasicStandardAndDicMiddleVo;
import cn.com.bluemoon.daps.standard.vo.BasicStandardAndDicVo;
import cn.com.bluemoon.daps.standard.entity.BasePublishInfoOfStandard;
import cn.com.bluemoon.daps.standard.entity.DapStandardBasic;
import cn.com.bluemoon.daps.standard.entity.DapStandardBasicDic;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotNull;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 基础标准表 服务类
 * </p>
 *
 * @author admin
 * @since 2020-08-03
 */
@Validated
public interface DapStandardBasicService extends IBmService<DapStandardBasic> {
    Logger LOGGER = LoggerFactory.getLogger(DapStandardBasicService.class);
    /**
     * 本地缓存，带超时ttl
     */
    Cache<String, Map<String, DapStandardBasic>> ALL_BASIC_STANDARD_CACHE = CacheBuilder.newBuilder()
            .initialCapacity(2000)
            .expireAfterAccess(10, TimeUnit.MINUTES)
            .build();
    String ALL_BASIC_STANDARD_DATA_KEY = "all_basic_standard_data";

    /**
     * true 为空合格，false为已存在
     *
     * @param model
     * @param checkTypes
     * @return
     */
    String checkModelOk(DapStandardBasic model, CheckType checkTypes);

    /**
     * 删除标准id
     * 对额外的流程、多版本数据，和被关联和被引用的数据 进行处理
     *
     * @param standardId
     * @param isLogicDel 是否为逻辑删除 默认为false
     */
    void deleteStandardBasicAndDic(@NotNull(message = "标准id不可为空") String standardId, boolean isLogicDel);

    /**
     * 只删除当前表单相关数据，不对额外的流程、多版本数据，和被关联和被引用的数据
     *
     * @param standardId 标准
     * @param isLogicDel 逻辑
     */
    void deleteSingleStandardBasicAndDic(String standardId, boolean isLogicDel);

    /**
     * 验证保存数据
     *
     * @param basicStandardAndDicVo
     * @return
     */
    BasicStandardAndDicVo checkAndThenSaveOrUpdate(BasicStandardAndDicVo basicStandardAndDicVo);

    /**
     * 查看标准数据中的关联模型信息
     *
     * @param id
     * @return
     */
    List<BasicStandardAndDicVo.ModelTableInfo> relateModelTableDataById(String id);

    /**
     * 根据标准唯一id
     *
     * @param standardUniqueId
     * @return
     */
    List<BasicStandardAndDicVo.ModelTableInfo> relateModelTableDataByStandardUniqueId(String standardUniqueId);

    /**
     * 解析基础标准导入模板 sheet1
     *
     * @param filePath
     * @return
     */
    ExcelImportResult<BasicStandardAndDicVo> parserSheet1(String filePath);

    /**
     * 解析基础标准导入模板 sheet2
     *
     * @param filePath
     * @return
     */
    ExcelImportResult<BasicStandardAndDicMiddleVo> parserSheet2(String filePath);

    /**
     * 解析基础标准导入模板 sheet3
     *
     * @param filePath
     * @return
     */
    ExcelImportResult<DapStandardBasicDic> parserSheet3(String filePath);

    /**
     * 翻译字典信息
     *
     * @param sourceStandardBasic
     * @param targetStandardBasic
     */
    void transferDicInfo(DapStandardBasic sourceStandardBasic, BasicStandardAndDicVo targetStandardBasic);

    /**
     * 获取所有已发布的标准数据 缓存存储
     *
     * @return Map<String, DapStandardBasic>
     */
    default Map<String, DapStandardBasic> findAllPublishGroupByStandardUniqueId() {
        try {
            return ALL_BASIC_STANDARD_CACHE.get(ALL_BASIC_STANDARD_DATA_KEY, () -> {
                LambdaQueryWrapper<DapStandardBasic> where = bmLambdaQuery().eq(DapStandardBasic::getPublishNewest, Boolean.TRUE)
                        .isNotNull(DapStandardBasic::getStandardUniqueId).orderByDesc(DapStandardBasic::getPublishTime);
                Map<String, DapStandardBasic> collect = list(where).stream().collect(Collectors.toMap(BasePublishInfoOfStandard::getStandardUniqueId, e -> e, (a, b) -> a));
                return collect;
            });
        } catch (ExecutionException e) {
            LOGGER.error("获取缓存已发布的基础标准数据失败，" + e.getMessage());
        }
        return Collections.emptyMap();
    }
}
